//
//  MatchmakingClient.m
//  ProjectW
//
//  Created by Nguyen Tan Loc on 7/21/12.
//  Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//

#import "MatchmakingClient.h"

@implementation MatchmakingClient

@synthesize availableServers = _availableServers;
@synthesize session = _session;
@synthesize delegate = _delegate;

-(id) init
{
    if (self = [super init])
    {
        _clientState = ClientStateIdle;
    }
    return self;
}

-(void) startSearchingForServerWithSessionID:(NSString *)sessionID
{
    if (_clientState == ClientStateIdle)
    {
        _clientState = ClientStateSearchingForServer;
        _availableServers = [NSMutableArray arrayWithCapacity:0];
        
        _session = [[GKSession alloc] initWithSessionID:sessionID displayName:nil sessionMode:GKSessionModeClient];
        _session.delegate = self;
        _session.available = YES;
    }
}

-(void) connectToServerWithPeerID:(NSString *)peerID
{
    NSAssert(_clientState == ClientStateSearchingForServer, @"Wrong state");
    
    _clientState = ClientStateConnecting;
    _serverPeerID = peerID;
    [_session connectToPeer:_serverPeerID withTimeout:_session.disconnectTimeout]; // Default is 20 seconds
}

-(int) getAvailableServerCount
{
    return [_availableServers count];
}

-(NSString*) getPeerIDForAvailableServerAtIndex:(int)index
{
    return [_availableServers objectAtIndex:index];
}

-(NSString*) getDisplayNameForPeerID:(NSString*)peerID
{
    return [_session displayNameForPeer:peerID];
}

-(void) session:(GKSession *)session peer:(NSString *)peerID didChangeState:(GKPeerConnectionState)state
{
    NSLog(@"MatchmakingClient: peer %@ changed state %d", peerID, state);
    switch (state) {
        case GKPeerStateAvailable: // When a server appear
            if (_clientState == ClientStateSearchingForServer)
            {
                if (![_availableServers containsObject:peerID])
                {
                    [_availableServers addObject:peerID];
                    [_delegate matchmakingClient:self serverBecameAvailable:peerID];
                }
            }
            break;
        case GKPeerStateUnavailable: // When a server disappear
            if (_clientState == ClientStateSearchingForServer)
            {
                if ([_availableServers containsObject:peerID])
                {
                    [_availableServers removeObject:peerID];
                    [_delegate matchmakingClient:self serverBecameUnavailable:peerID]; 
                }
            }
            break;
        case GKPeerStateConnecting:
            break;
        case GKPeerStateConnected:
            if (_clientState == ClientStateConnecting)
            {
                _clientState = ClientStateConnected;
            }
            break;
        case GKPeerStateDisconnected:
            if (_clientState == ClientStateConnected)
            {
                [self disconnectFromServer];
            }
            break;
        default:
            break;
    }
}

-(void) disconnectFromServer
{
    _clientState = ClientStateIdle;
    [_session disconnectFromAllPeers];
    _session.available = NO;
    _session.delegate = nil;
    _session = nil;
    
    _availableServers = nil;
    
    [_delegate matchmakingClient:self didDisconnectFromServer:_serverPeerID];
    _serverPeerID = nil;
}

-(void) session:(GKSession *)session didReceiveConnectionRequestFromPeer:(NSString *)peerID
{
    NSLog(@"MatchmakingClient: connection request from peer %@", peerID);
}

-(void) session:(GKSession *)session connectionWithPeerFailed:(NSString *)peerID withError:(NSError *)error
{
    NSLog(@"MatchmakingClient: connection with peer %@ failed %@", peerID, error);
    
    [self disconnectFromServer];
}

-(void) session:(GKSession *)session didFailWithError:(NSError *)error
{
    NSLog(@"MatchmakingClient: session failed %@", error);
    
    if ([[error domain] isEqualToString:GKSessionErrorDomain])
    {
        if ([error code] == GKSessionCannotEnableError)
        {
            [_delegate matchmakingClientNoNetwork:self];
            [self disconnectFromServer];
        }
    }
}

@end
